/* Copyright (c) 2024 Qualcomm Technologies International, Ltd. */
/* %%version */

#ifndef GATT_OTS_CLIENT_PRIVATE_H_
#define GATT_OTS_CLIENT_PRIVATE_H_

#include <stdio.h>

#include "csr_bt_usr_config.h"
#include "csr_bt_profiles.h"
#include "csr_bt_gatt_client_util_lib.h"
#include "csr_bt_cm_lib.h"
#include "gatt_ots_client.h"
#include "gatt_ots_client_debug.h"

#define OTSC_OBJECT_SIZE                                (4)

/* Size of the Client Characteristic Configuration in number of octects */
#define GATT_OTS_CLIENT_CHARACTERISTIC_CONFIG_SIZE      (2)

#define GATT_ATTR_HANDLE_INVALID                        ((uint16) 0x0000)

#define GattOtscMessageSend(TASK, ID, MSG) {\
    MSG->id = ID; \
    CsrSchedMessagePut(TASK, OTS_CLIENT_PRIM, MSG);\
    }

typedef uint32                                          OtscPendingOp;
/* Start of pending operations used while Init procedure */
#define OTSC_PENDING_OP_NONE                            ((OtscPendingOp) 0x00000000)
#define OTSC_PENDING_OP_READ_FEATURE_CHAR               ((OtscPendingOp) 0x00000001)
#define OTSC_PENDING_OP_WRITE_OACP_CCCD                 ((OtscPendingOp) 0x00000002)
#define OTSC_PENDING_OP_WRITE_OLCP_CCCD                 ((OtscPendingOp) 0x00000004)
/* End */
#define OTSC_PENDING_OP_WRITE_OTHER_CCCD                ((OtscPendingOp) 0x00000008)
#define OTSC_PENDING_OP_OLCP_PROCEDURE                  ((OtscPendingOp) 0x00000010)
#define OTSC_PENDING_OP_OACP_PROCEDURE                  ((OtscPendingOp) 0x00000020)
#define OTSC_PENDING_OP_READ_CHARS_FOR_OBJ_CONTENT      ((OtscPendingOp) 0x00000040)
#define OTSC_PENDING_OP_READ_OBJ_CONTENT                ((OtscPendingOp) 0x00000080)
#define OTSC_PENDING_OP_READ_OBJECT_METADATA_PROCEDURE  ((OtscPendingOp) 0x00000100)
#define OTSC_PENDING_OP_ABORT_PROCEDURE                 ((OtscPendingOp) 0x00000200)
#define OTSC_PENDING_OP_FILTER_OBJ                      ((OtscPendingOp) 0x00000400)

typedef uint32                                          OtscInternalMsg;
#define OTSC_INTERNAL_MSG_REG_INDICATION_REQ            ((OtscInternalMsg) 0x00000001)
#define OTSC_INTERNAL_MSG_SELECT_OBJ_REQ                ((OtscInternalMsg) 0x00000002)
#define OTSC_INTERNAL_MSG_READ_OBJ_REQ                  ((OtscInternalMsg) 0x00000003)
#define OTSC_INTERNAL_MSG_ABORT_REQ                     ((OtscInternalMsg) 0x00000004)
#define OTSC_INTERNAL_MSG_READ_OBJ_METADATA_REQ         ((OtscInternalMsg) 0x00000005)
#define OTSC_INTERNAL_MSG_FILTER_OBJ_REQ                ((OtscInternalMsg) 0x00000006)
#define OTSC_INTERNAL_MSG_OPEN_OTS_CHANNEL_REQ          ((OtscInternalMsg) 0x00000007)
#define OTSC_INTERNAL_MSG_CLOSE_OTS_CHANNEL_REQ         ((OtscInternalMsg) 0x00000008)

typedef uint8                                           OtscObjChangedFlagMask;
#define OTSC_OBJ_CHANGE_SOURCE                          ((OtscObjChangedFlagMask) 0x01)
#define OTSC_OBJ_CONTENT_CHANGED                        ((OtscObjChangedFlagMask) 0x02)
#define OTSC_OBJ_METADATA_CHANGED                       ((OtscObjChangedFlagMask) 0x04)
#define OTSC_OBJ_CREATED                                ((OtscObjChangedFlagMask) 0x08)
#define OTSC_OBJ_DELETED                                ((OtscObjChangedFlagMask) 0x10)

typedef struct otscReadObjContentInfo
{
    uint32                  offset;
    uint32                  length;
    CsrBtConnId             connId;
    uint32                  objSizeRcvd;  /* Size of the object has been received */
    uint8                   mtu;
} otscReadObjContentInfo;

/*
    @brief Client library private data.
*/
typedef struct
{
    /* Peer device's discovered handles and other information */
    GattOtscDeviceData      deviceData;

    /* GattId, cid and service handle is a part of this structure */
    ServiceHandleListElm_t *srvcElem;

    /* Holds id of running timer (outstanding OLCP/OACP procedures)*/
    CsrSchedTid             timerId;

    /* OTSC lib task */
    AppTask                 libTask;

    /* Application's task*/
    AppTask                 appTask;

    /* OTS L2cap connection ID */
    CsrBtConnId             btConnId;

    /* Any read/write command pending */
    OtscPendingOp           pendingCmd;

    /* To store the handle of the characteristic when a descriptor discovery is pending */
    CsrUint16               pendingHandle;

    /* To track total write requests made to GATT */
    uint8                   writeCccCount;

    /* Ongoing OLCP procedure */
    GattOtscObjListOpcode   opcode;

    /* Ongoing read object info */
    otscReadObjContentInfo  readObjContentInfo;

    /* To track the no of GATT write REQs to multiple filter characteristic instances */
    uint8                   filtersCount;
} GOTSC; /* GOTSC : GATT OTS Client */

#define OTSC_START_OACP_TIMER(gattOtsClient) \
                CsrSchedTimerSet((1000 * OTS_OACP_TIMEOUT), \
                                 (void (*) (uint16, void *)) oacpTimeOutHandler, \
                                 0, \
                                 (void *) gattOtsClient);

#define OTSC_START_OLCP_TIMER(gattOtsClient) \
                CsrSchedTimerSet((1000 * OTS_OLCP_TIMEOUT), \
                                 (void (*) (uint16, void *)) olcpTimeOutHandler, \
                                 0, \
                                 (void *) gattOtsClient);

#define OTSC_START_READ_OBJECT_TIMER(gattOtsClient) \
                CsrSchedTimerSet((1000 * OTS_READ_OBJECT_TIMEOUT), \
                                 (void (*) (uint16, void *)) readObjectTimeOutHandler, \
                                 0, \
                                 (void *) gattOtsClient);

/* Internal Message Structure to register for indication/notification request */
typedef struct
{
    OtscInternalMsg              id;
    ServiceHandle                svcHandle;
    GattOtscCharacValuesMask     charsValMask;
} OtscInternalMsgRegIndication;

/* Internal Message Structure to read a characteristic */
typedef struct
{
    OtscInternalMsg              id;
    ServiceHandle                svcHandle;
    GattOtscCharacteristicsId    characId;
} OtscInternalMsgRead;

/* Internal Message Structure to select a object */
typedef struct
{
    OtscInternalMsg              id;
    ServiceHandle                svcHandle;
    GattOtscObjectId             objectId;
    GattOtscObjListOpcode        opcode;
} OtscInternalMsgSelectObject;

/* Internal Message Structure to read a object */
typedef struct
{
    OtscInternalMsg              id;
    ServiceHandle                svcHandle;
    uint32                       offset;
    uint32                       length;
    CsrBtConnId                  connId;
} OtscInternalMsgReadObject;

/* Internal Message Structure to abort current read/write procedure */
typedef struct
{
    OtscInternalMsg              id;
    ServiceHandle                svcHandle;
} OtscInternalMsgAbort;

/* Internal Message Structure to read current object's metadata */
typedef struct
{
    OtscInternalMsg              id;
    ServiceHandle                svcHandle;
    GattOtscCharacteristicsId    characId;
} OtscInternalMsgReadObjectMetadata;

/* Internal Message Structure to read a object */
typedef struct
{
    OtscInternalMsg              id;
    ServiceHandle                svcHandle;
    CsrBtUuid                    objectUuid;
    GattOtscFilterByNameInfo    *nameInfo;
    GattOtscFilterByDateInfo    *dateInfo;
    GattOtscFilterByObjSizeInfo *objSizeInfo;
    GattOtscObjectFilters        filters;
} OtscInternalMsgFilterObject;

/* Internal Message Structure to open/close the OTS channel */
typedef struct
{
    OtscInternalMsg              id;
    ServiceHandle                svcHandle;
} OtscInternalMsgOpenOrCloseOtsChannel;

typedef struct
{
    CsrCmnList_t serviceHandleList;
} GattOtsClient;
#endif /* GATT_OTS_CLIENT_PRIVATE_H_ */

